package com.xianyun.site.iblog.common;

import com.alibaba.fastjson.JSONObject;
import com.xianyun.site.iblog.common.database.RocketMqTransactionLogMapper;
import com.xianyun.site.iblog.common.database.domainobject.RocketMqTransactionLog;
import com.xianyun.site.iblog.gatewayimpl.database.SystemUserMapper;
import com.xianyun.site.iblog.gatewayimpl.database.domainobject.SystemUserDO;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.apache.rocketmq.spring.support.RocketMQHeaders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.security.SecureRandom;


/**
 * @author 朱永杰
 */
@Component
@RocketMQTransactionListener
public class RegisterMqTransactionListener implements RocketMQLocalTransactionListener {
    private final Logger logger = LoggerFactory.getLogger(RegisterMqTransactionListener.class);
    @Autowired
    private SystemUserMapper userMapper;

    @Autowired
    private RocketMqTransactionLogMapper rocketMqTransactionLogMapper;

    /**
     * 执行本地事务
     */
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object o) {
        //解析消息内容
        MessageHeaders headers = message.getHeaders();
        try {
            String jsonString = new String((byte[]) message.getPayload());
            JSONObject jsonObject = JSONObject.parseObject(jsonString);
            SystemUserDO userSave = JSONObject.parseObject(jsonObject.getString("System_User"), SystemUserDO.class);
            //获取事务ID
            String transactionId = (String) headers.get(RocketMQHeaders.TRANSACTION_ID);
            saveSystemUser(userSave,transactionId);
            return RocketMQLocalTransactionState.COMMIT;
        } catch (Exception e) {
            logger.error("executeLocalTransaction 事务执行失败",e);
            return RocketMQLocalTransactionState.ROLLBACK;
        }
    }
    /**
     * 事务回查
     * @param message 消息
     * @return 本地事务结果
     */
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {

        MessageHeaders headers = message.getHeaders();
        //获取事务ID
        String transactionId = (String) headers.get(RocketMQHeaders.TRANSACTION_ID);
        logger.info("检查本地事务,事务ID:{}",transactionId);
        //根据事务id从日志表检索
        RocketMqTransactionLog rocketmqTransactionLog = rocketMqTransactionLogMapper.selectTransactionLogByTid(transactionId);
        if(null != rocketmqTransactionLog){
            logger.info("log: 本地事务编号:{}",rocketmqTransactionLog.getId());
            return RocketMQLocalTransactionState.COMMIT;
        }
        return RocketMQLocalTransactionState.ROLLBACK;

    }

    /**
     * 保存用户
     * @param userSave 用户
     * @param transactionId 事务编号
     * TODO 实现注册成功之后发送注册结果功能
     *                      考虑清楚如何和现有系统和体系相结合
     */
    private void saveSystemUser(SystemUserDO userSave,String transactionId){
        SecureRandom secureRandom=new SecureRandom();
        userSave.setUserId(Long.decode(((secureRandom.nextInt() * 9 + 1) * 1000000) +""));
        //保存用户
        userMapper.saveSystemUser(userSave);
        //插入事务表
        rocketMqTransactionLogMapper.insertRocketMqTransactionLog(
                RocketMqTransactionLog.builder()
                        .transactionId(transactionId)
                        .log("执行创建用户操作,用户名:"+userSave.getUserName())
                        .build()
        );
    }
}
